package com.meviewer.common;

import android.util.Log;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * @author hanhaoran
 * 异步线程池，用来提交异步任务，可以同步/异步获取结果
 */
public final class Worker {
    private Worker() {}

    private static final ExecutorService WORKER;

    static {
        WORKER = new ThreadPoolExecutor(
                Runtime.getRuntime().availableProcessors() / 2,
                Runtime.getRuntime().availableProcessors(),
                Constants.ONE,
                TimeUnit.MINUTES,
                new LinkedBlockingQueue<>(Constants.INT32),
                new ThreadFactoryBuilder().setDaemon(true).setNameFormat("worker-%d").build(),
                ((r, executor) -> Log.w(Worker.class.getName(), "Work ignored by worker..."))
        );
        Runtime.getRuntime().addShutdownHook(new Thread(WORKER::shutdown));
    }

    public static void execute(Runnable task) {
        WORKER.execute(task);
    }

    public static <V> void async(Callable<V> task, Consumer<V> handler) {
        CompletableFuture<V> future = CompletableFuture.supplyAsync(() -> {
            try {
                return task.call();
            } catch (Exception e) {
                return null;
            }
        }, WORKER);
        future.thenAccept(handler);
    }

    public static <V> void sync(Callable<V> task, Consumer<V> handler) {
        V res = null;
        try {
            res = submit(task).get();
        } catch (Exception e) {
        }
        handler.accept(res);
    }

    public static <V> Future<V> submit(Callable<V> task) {
        return WORKER.submit(task);
    }
}
